package com.easygem.system.service.impl;

import com.easygem.common.enums.system.UserStatusEnum;
import com.easygem.common.enums.system.UserTypeEnum;
import com.easygem.common.error.SystemCodeEnum;
import com.easygem.common.error.SystemException;
import com.easygem.common.model.system.*;
import com.easygem.common.response.ActiveUser;
import com.easygem.common.utils.MenuTreeBuilder;
import com.easygem.common.vo.system.*;
import com.easygem.system.converter.MenuConverter;
import com.easygem.system.jwt.JWTToken;
import com.easygem.system.jwt.JWTUtils;
import com.easygem.system.mapper.*;
import com.easygem.system.service.DepartmentEmpService;
import com.easygem.system.service.EmployeeService;
import com.easygem.system.util.MD5Utils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.util.*;

/**
 * @Author 文晓平
 * @Date 2024/12/7 15:44
 * @Version 1.0
 **/
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private DeptEmpMapper departmentMapper;

    @Autowired
    private DepartmentEmpService departmentClientService;

    /**
     * 查询用户
     * @param name 用户名
     * @return
     */
    @Override
    public Employee findEmployeeByName(String name) {
        //        User t = new User();
//        t.setUserName(name);
//        t.setAccountName(accountName);
        Example o = new Example(Employee.class);
        o.createCriteria().andNotEqualTo("status",-2).andEqualTo("empName",name);
        return  employeeMapper.selectOneByExample(o);
    }

    /**
     * 查询用户角色
     * @param id 用户ID
     * @return
     */
    @Override
    public List<Role> findRolesById(Long id) throws SystemException {
        Employee employee = employeeMapper.selectByPrimaryKey(id);
        if(employee==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该用户不存在");
        }
        List<Role> roles=new ArrayList<>();
        EmployeeRole t = new EmployeeRole();
        t.setUserId(employee.getEmpId());
        List<EmployeeRole> userRoleList = userRoleMapper.select(t);
        List<Long> rids=new ArrayList<>();
        if(!CollectionUtils.isEmpty(userRoleList)){
            for (EmployeeRole employeeRole : userRoleList) {
                rids.add(employeeRole.getRoleId());
            }
            if(!CollectionUtils.isEmpty(rids)){
                for (Long rid : rids) {
                    Role role = roleMapper.selectByPrimaryKey(rid);
                    if(role!=null){
                        roles.add(role);
                    }
                }
            }
        }
        return roles;
    }

    /**
     * 查询权限
     * @param roles 用户的角色
     * @return
     */
    @Override
    public List<Menu> findMenuByRoles(List<Role> roles) {
        List<Menu> menus=new ArrayList<>();
        if(!CollectionUtils.isEmpty(roles)){
            Set<Long> menuIds=new HashSet<>();//存放用户的菜单id
            List<RoleMenu> roleMenus;
            for (Role role : roles) {
                //根据角色ID查询权限ID
                Example o = new Example(RoleMenu.class);
                o.createCriteria().andEqualTo("roleId",role.getRoleId());
                roleMenus= roleMenuMapper.selectByExample(o);
                if(!CollectionUtils.isEmpty(roleMenus)){
                    for (RoleMenu roleMenu : roleMenus) {
                        menuIds.add(roleMenu.getMenuId());
                    }
                }
            }
            if(!CollectionUtils.isEmpty(menuIds)){
                for (Long menuId : menuIds) {
                    //该用户所有的菜单
                    Menu menu = menuMapper.selectByPrimaryKey(menuId);
                    if(menu!=null){
                        menus.add(menu);
                    }
                }
            }
        }
        return menus;
    }

    /**
     * 获取菜单
     * @return
     */
    @Override
    public List<MenuNodeVO> findMenu() {
        List<Menu> menus=null;
        List<MenuNodeVO> menuNodeVOS=new ArrayList<>();
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(activeUser.getEmployee().getType()== UserTypeEnum.SYSTEM_ADMIN.getTypeCode()){
            //超级管理员
            menus=menuMapper.selectAll();
        }else if(activeUser.getEmployee().getType()== UserTypeEnum.SYSTEM_USER.getTypeCode()){
            //普通系统用户
            menus= activeUser.getMenus();
        }
        if(!CollectionUtils.isEmpty(menus)){
            menuNodeVOS= MenuConverter.converterToMenuNodeVO(menus);
        }

        //构建树形菜单
        return MenuTreeBuilder.build(menuNodeVOS);

    }

    /**
     * 用户列表
     * @param employeeVO
     * @return
     */
    @Override
    public PageVO<Employee> findEmployeeList(Integer pageNum, Integer pageSize, EmployeeVO employeeVO) {
        PageHelper.startPage(pageNum,pageSize);

        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeVO,employee);
        employee.setStatus(employeeVO.getStatus());
        employee.setEmpName(employeeVO.getEmpName());
        employee.setPhone(employeeVO.getPhone());
        employee.setNickName(employeeVO.getNickName());
        //获得登录用户所在部门及以下部门编号
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        //得到所有部门列表
//        List<DeptClient> deptClients = departmentMapper.selectAll();
//        List<Long> ids = DepUtils.getDepartmentAndChildrenIds(deptClients, activeUser.getEmployee().getDeptId());
//        employee.setIds(ids);
        List<Employee> userList = employeeMapper.selectEmployeeList(employee);
        for (Employee user : userList) {
            if (user.getType()!=null&&user.getType()==0) {
                user.setRoleName("超级管理员");
            }
            if (user.getRoleName()==null){
                user.setRoleName("暂无");
            }
        }
        PageInfo<Employee> info=new PageInfo<>(userList);
        return new PageVO<>(info.getTotal(),userList);
    }

    /**
     * 根据部门编号查询用户列表
     *
     * @param deptId 部门编号
     * @return
     */
    @Override
    public List<EmployeeVO> findEmployeeListByDept(Long deptId) {
        return employeeMapper.findEmployeeListByDept(deptId);
    }

    /**
     * 删除用户
     * @param id 用户ID
     */
    @Transactional
    @Override
    public void deleteById(Long id) throws SystemException {
        Employee user = employeeMapper.selectByPrimaryKey(id);
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();

        if(user==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要下线的用户不存在");
        }

        if(user.getEmpId().equals(activeUser.getEmployee().getEmpId())){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"不能删除当前登入用户");
        }

        employeeMapper.deleteByPrimaryKey(id);
        //删除对应[用户-角色]记录
        Example o = new Example(EmployeeRole.class);
        o.createCriteria().andEqualTo("empId",id);
        userRoleMapper.deleteByExample(o);
    }

    /**
     * 更新用户禁用状态
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(Long id, Boolean status) throws SystemException {
        Employee employee = employeeMapper.selectByPrimaryKey(id);
        if(employee==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要更新状态的用户不存在");
        }
        ActiveUser activeUser= (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(employee.getEmpId().equals(activeUser.getEmployee().getEmpId())){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"无法改变当前用户状态");
        }else {
            Employee t = new Employee();
            t.setEmpId(id);
            t.setStatus(status? UserStatusEnum.DISABLE.getStatusCode() :
                    UserStatusEnum.AVAILABLE.getStatusCode());
            employeeMapper.updateByPrimaryKeySelective(t);
        }
    }

    /**
     * 添加用户
     * @param employeeVO
     */
    @Transactional
    @Override
    public void add(EmployeeVO employeeVO) throws SystemException {
        @NotBlank(message = "用户名不能为空") String empName = employeeVO.getEmpName();
        @NotNull(message = "部门id不能为空") Long departmentId = employeeVO.getDeptId();
        Example o = new Example(Employee.class);
        o.createCriteria().andEqualTo("empName",empName);
        int i = employeeMapper.selectCountByExample(o);
        if(i!=0){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该用户名已被占用");
        }
        DeptEmp department = departmentMapper.selectByPrimaryKey(departmentId);
        if(department==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该部门不存在");
        }
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeVO,employee);
        String salt=UUID.randomUUID().toString().substring(0,32);
        employee.setPassword(MD5Utils.md5Encryption(employee.getPassword(), salt));
        employee.setEditTime(new Timestamp(System.currentTimeMillis()));
        employee.setCreateTime(new Timestamp(System.currentTimeMillis()));
        //获得到登录后的用户信息，通用方式
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        employee.setSalt(salt);
        employee.setStatus(UserStatusEnum.AVAILABLE.getStatusCode());//添加的用户默认启用
        //user.setAvatar("http://badidol.com/uploads/images/avatars/201910/24/18_1571921832_HG9E55x9NY.jpg");
        employeeMapper.insert(employee);
    }

    /**
     * 更新
     * @param id
     * @param employeeEditVO
     */
    @Transactional
    @Override
    public void update(Long id, EmployeeEditVO employeeEditVO) throws SystemException {
        Employee employee = employeeMapper.selectByPrimaryKey(id);
        @NotBlank(message = "登录名不能为空") String empName = employeeEditVO.getEmpName();
        @NotNull(message = "部门不能为空") Long departmentId = employeeEditVO.getDeptId();
        if(employee==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要删除的用户不存在");
        }
        DeptEmp department = departmentMapper.selectByPrimaryKey(departmentId);
        if(department==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该部门不存在");
        }
        Example o = new Example(Employee.class);
        o.createCriteria().andEqualTo("empName",empName);
        List<Employee> employees = employeeMapper.selectByExample(o);
        if(!CollectionUtils.isEmpty(employees)){
            if(!employees.get(0).getEmpId().equals(id)){
                throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该用户名已被占用");
            }
        }
        Employee employee1 = new Employee();
        BeanUtils.copyProperties(employeeEditVO,employee1);
        employee1.setEditTime(new Timestamp(System.currentTimeMillis()));
        employee1.setEmpId(employeeEditVO.getEmpId());
        employee1.setDeptId(employeeEditVO.getDeptId());
        employeeMapper.updateByPrimaryKeySelective(employee1);
    }

    /**
     * 编辑
     * @param id
     * @return
     */
    @Transactional
    @Override
    public EmployeeEditVO edit(Long id) throws SystemException {
        Employee employee = employeeMapper.selectByPrimaryKey(id);
        if(employee==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要编辑的用户不存在");
        }
        EmployeeEditVO employeeEditVO = new EmployeeEditVO();
        BeanUtils.copyProperties(employee,employeeEditVO);
        DeptEmp department = departmentMapper.selectByPrimaryKey(employee.getDeptId());
        if(department!=null){
            employeeEditVO.setDeptId(department.getDeptId());
        }
        return employeeEditVO;
    }

    /**
     * 用户拥有的角色ID
     * @param id 用户id
     * @return
     */
    @Transactional
    @Override
    public List<Long> roles(Long id) throws SystemException {
        Employee employee = employeeMapper.selectByPrimaryKey(id);
        if(employee==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该用户不存在");
        }
        Example o = new Example(EmployeeRole.class);
        o.createCriteria().andEqualTo("empId",employee.getEmpId());
        List<EmployeeRole> employeeRoleList = userRoleMapper.selectByExample(o);
        List<Long> roleIds=new ArrayList<>();
        if(!CollectionUtils.isEmpty(employeeRoleList)){
            for (EmployeeRole userRole : employeeRoleList) {
                Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                if(role!=null){
                    roleIds.add(role.getRoleId());
                }
            }
        }
        return roleIds;
    }

    /**
     * 分配角色
     * @param id 用户id
     * @param roleId 角色数组
     */
    @Override
    @Transactional
    public void assignRoles(Long id, Long roleId) throws SystemException {
        //删除之前用户的所有角色
        Employee user = employeeMapper.selectByPrimaryKey(id);
        if(user==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"用户不存在");
        }
        //更新用户角色
        //userMapper.updateRole(user.getUserId(),roleId);
        //删除之前分配的
        Example o = new Example(EmployeeRole.class);
        o.createCriteria().andEqualTo("empId",user.getEmpId());
        userRoleMapper.deleteByExample(o);
        //增加现在分配的
        Role role = roleMapper.selectByPrimaryKey(roleId);
        if(role==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"roleId="+roleId+",该角色不存在");
        }
        //判断角色状态
        if(role.getStatus()==0){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"roleName="+role.getRoleName()+",该角色已禁用");
        }
        EmployeeRole userRole = new EmployeeRole();
        userRole.setEmpId(id);
        userRole.setRoleId(roleId);
        userRoleMapper.insert(userRole);

        /*
        //删除之前分配的
        Example o = new Example(UserRole.class);
        o.createCriteria().andEqualTo("userId",user.getUserId());
        userRoleMapper.deleteByExample(o);
        //增加现在分配的
        if(rids.length>0){
            for (Long rid : rids) {
                Role role = roleMapper.selectByPrimaryKey(rid);
                if(role==null){
                    throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"roleId="+rid+",该角色不存在");
                }
                //判断角色状态
                if(role.getStatus()==0){
                    throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"roleName="+role.getRoleName()+",该角色已禁用");
                }
                UserRole userRole = new UserRole();
                userRole.setUserId(id);
                userRole.setRoleId(rid);
                userRoleMapper.insert(userRole);
            }
        }
        */
    }

    @Override
    public List<Employee> findAll() {
        Employee employee = new Employee();
        //获得登录用户所在部门及以下部门编号
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        //得到所有部门列表
        List<DeptEmp> deptClients = departmentMapper.selectAll();
//        List<Long> ids = DepUtils.getDepartmentAndChildrenIds(deptClients, activeUser.getEmployee().getDeptId());
//        employee.setIds(ids);
        List<Employee> userList = employeeMapper.selectEmployeeList(employee);

        //return userMapper.selectAll();
        return userList;
    }

    /**
     * 用户登入
     * @param username
     * @param password
     * @return
     */
    @Override
    public String login(String username, String password) throws SystemException {
        String token;
        //1.先查询用户信息
        Employee user = findEmployeeByName(username);
        if (user != null) {
            if(user.getStatus()==-1){
                throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该员工已被冻结");
            }
            //密码盐
            String salt = user.getSalt();
            //秘钥为盐
            String target = MD5Utils.md5Encryption(password, salt);
            //根据用户名和密码盐 生成Token
            token = JWTUtils.sign(username, target);
            JWTToken jwtToken = new JWTToken(token);
            try {
                //去登陆
                SecurityUtils.getSubject().login(jwtToken);
                /**
                 * 1.登录后需要认证：UserRealm。doGetAuthenticationInfo()
                 */
            } catch (AuthenticationException e) {
                throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,e.getMessage());
            }
        } else {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"用户不存在");
        }
        return token;
    }

    /**
     * 用户详情
     *
     * @return
     */
    @Override
    public EmployeeInfoVO info() throws SystemException {
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        EmployeeInfoVO employeeInfoVO = new EmployeeInfoVO();
        employeeInfoVO.setAvatar(activeUser.getEmployee().getAvatar());
        employeeInfoVO.setEmpName(activeUser.getEmployee().getEmpName());
        employeeInfoVO.setUrl(activeUser.getUrls());
        employeeInfoVO.setNickName(activeUser.getEmployee().getNickName());
//        List<String> roleNames = activeUser.getRoles().stream().map(Role::getRoleName).collect(Collectors.toList());
//        employeeInfoVO.setRoles(roleNames);
        employeeInfoVO.setRoleName(activeUser.getRole().getRoleName());
        employeeInfoVO.setPerms(activeUser.getPermissions());
        employeeInfoVO.setIsAdmin(activeUser.getEmployee().getType()==UserTypeEnum.SYSTEM_ADMIN.getTypeCode());
        DepartmentVO dept = departmentClientService.edit(activeUser.getEmployee().getDeptId());
        if(dept!=null){
            employeeInfoVO.setDepartment(dept.getDeptName());
        }
        return employeeInfoVO;
    }

    /**
     * 更新用户状态
     *
     * @param userId 用户编号
     * @param status 用户状态
     * @return
     */
    @Override
    public void updateEmployeeStatus(Long userId, Integer status)throws SystemException {
        Employee employee = employeeMapper.selectByPrimaryKey(userId);
        if(employee==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要更新状态的员工不存在");
        }
        ActiveUser activeUser= (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(employee.getEmpId().equals(activeUser.getEmployee().getEmpId())){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"无法改变当前员工状态");
        }else {
            Employee t = new Employee();
            t.setEmpId(userId);
            t.setStatus(status);
            employeeMapper.updateByPrimaryKeySelective(t);
        }
    }

    /**
     * 更新多个用户状态
     *
     * @param map 多个用户编号，用户状态
     * @return
     */
    @Override
    public void updateEmployeeStatusMore(Map<String, Object> map) throws SystemException {
        employeeMapper.updateEmployeeStatusMore(map);
    }

    @Override
    public List<Employee> findEmployeeList() {
        List<Employee> employeeList = employeeMapper.selectEmployee();
        return employeeList;
    }
    /**
     * 查询用户角色
     * @param userId 用户ID
     * @return
     */
    @Override
    public Role findRoleById(Long userId) throws SystemException {
//        User dbUser = userMapper.selectByPrimaryKey(userId);
//        if(dbUser==null){
//            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该用户不存在");
//        }
        EmployeeRole t = new EmployeeRole();
        t.setEmpId(userId);
        EmployeeRole ur = userRoleMapper.selectOne(t);
        Role role = roleMapper.selectByPrimaryKey(ur.getRoleId());

        return role;
    }

    /**
     * 根据用户角色查询用户的菜单
     * 菜单: menu+button
     *
     * @param role 用户的角色
     * @return
     */
    @Override
    public List<Menu> findMenuByRole(Role role) {
        List<Menu> menus=new ArrayList<>();
        if(role!=null){
            List<Long> menuIds=new ArrayList<>();//存放用户的菜单id
            //根据角色ID查询权限ID
            Example o = new Example(RoleMenu.class);
            o.createCriteria().andEqualTo("roleId",role.getRoleId());
            List<RoleMenu> roleMenus= roleMenuMapper.selectByExample(o);
            if(!CollectionUtils.isEmpty(roleMenus)){
                for (RoleMenu roleMenu : roleMenus) {
                    menuIds.add(roleMenu.getMenuId());
                }
            }
            if(!CollectionUtils.isEmpty(menuIds)){
//                for (Long menuId : menuIds) {
//                    //该用户所有的菜单
//                    Menu menu = menuMapper.selectByPrimaryKey(menuId);
//                    if(menu!=null){
//                        menus.add(menu);
//                    }
//                }
                menus = menuMapper.getMenus(menuIds);
            }
        }
        return menus;
    }

    /**
     * 判断输入值与原密码是否一致
     *
     * @param rawPwd
     */
    @Override
    public boolean isFitRawPwd(String rawPwd) {
        boolean isOK = false;
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Employee employeeMain = activeUser.getEmployee();
        //1、先判断账户是否被禁用
        Employee employee = findEmployeeByName(employeeMain.getEmpName());
        if (employee != null) {
            //密码盐
            String salt = employee.getSalt();
            //加密
            String rawpwd = MD5Utils.md5Encryption(rawPwd, salt);
            //获取原密码
            String password = employee.getPassword();
            //进行对比
            isOK = (password.equals(rawpwd));
        }
        return isOK;
    }

    /**
     * 修改密码
     *
     * @param newPwd 新密码
     */
    @Override
    public void editPwd(String newPwd) {
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Employee employeeMain = activeUser.getEmployee();
        String pwd=MD5Utils.md5Encryption(newPwd,employeeMain.getSalt());
        employeeMapper.editPwd(employeeMain.getEmpId(),pwd);
        employeeMain.setPassword(pwd);
    }

    /**
     * 根据用户编号得到用户角色
     *
     * @param userId 用户编号
     * @return
     * @throws SystemException
     */
    @Override
    public Long getUserRole(Long userId) throws SystemException {
        Employee user = employeeMapper.selectByPrimaryKey(userId);
        if(user==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该员工不存在");
        }
        Long roleId = employeeMapper.getUserRole(user.getEmpId());
        return roleId;
    }

}
